package com.loong.shop.business;

import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Lists;
import com.loong.common.executor.AsyncExecutor;
import com.loong.common.mybatis.business.AbstractBusiness;
import com.loong.common.rabbitmq.dto.GoodsBaseDTO;
import com.loong.common.rabbitmq.dto.GoodsSkuDTO;
import com.loong.common.rabbitmq.dto.base.RepositoryEventDto;
import com.loong.common.redis.RedisTools;
import com.loong.common.utils.TransformUtils;
import com.loong.global.constant.RedisKey;
import com.loong.shop.common.backend.param.GoodsSkuQueryParam;
import com.loong.shop.mapper.GoodsSkuMapper;
import com.loong.shop.model.GoodsBase;
import com.loong.shop.model.GoodsSku;
import com.loong.shop.mq.GoodsReport;
import com.loong.shop.mq.GoodsSkuReport;
import com.loong.shop.result.GoodsMaxAndMinPriceResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Condition;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description:
 * @Author: 刘群
 * @Date: 2020/10/27 7:48
 */
@Slf4j
@Repository
public class GoodsSkuBusiness extends AbstractBusiness<GoodsSku> {

    @Resource
    private GoodsSkuMapper skuMapper;

    @Resource
    GoodsReport goodsReport;

    @Resource
    GoodsSkuReport goodsSkuReport;

    @Resource
    private AsyncExecutor asyncExecutor;

    @Resource
    private GoodsBaseBusiness goodsBaseBusiness;

    /**
     * 根据查询参数查询商品sku
     *
     * @param param 查询参数
     * @return 商品sku集合
     */
    public List<GoodsSku> findGoodsSkuByParam(GoodsSkuQueryParam param) {
        Condition condition = new Condition(GoodsSku.class);
        Example.Criteria criteria = condition.createCriteria();
        if (ObjectUtils.isNotEmpty(param.getGoodsBaseId())) {
            criteria.andEqualTo("goodsBaseId", param.getGoodsBaseId());
        }
        if (ObjectUtils.isNotEmpty(param.getGoodsSpecification())) {
            criteria.andEqualTo("goodsSpecification", JSONArray.toJSONString(param.getGoodsSpecification()));
        }
        if (ObjectUtils.isNotEmpty(param.getMinPrice())) {
            criteria.andGreaterThanOrEqualTo("currentPrice", param.getMinPrice());
        }
        if (ObjectUtils.isNotEmpty(param.getMaxPrice())) {
            criteria.andLessThanOrEqualTo("currentPrice", param.getMaxPrice());
        }
        if (ObjectUtils.isNotEmpty(param.getStartTime())) {
            criteria.andGreaterThanOrEqualTo("createTime", param.getStartTime());
        }
        if (ObjectUtils.isNotEmpty(param.getEndTime())) {
            criteria.andLessThanOrEqualTo("createTime", param.getEndTime());
        }
        return findByCondition(condition);
    }

    /**
     * 根据规格值id查询商品sku
     * @param sizeValueId 规格值id
     * @return 商品sku集合
     */
    public List<GoodsSku> findGoodsSkuBySizeValueId(Long sizeValueId){
        Condition condition = new Condition(GoodsSku.class);
        Example.Criteria criteria = condition.createCriteria();
        criteria.andLike("goodsSpecification","%"+sizeValueId+"%");
        return findByCondition(condition);
    }

    /**
     * 根据商品id查询商品详情
     *
     * @param goodsId 商品id
     * @return 商品sku集合
     */
    public List<GoodsSku> findGoodsSkuByGoodsId(Long goodsId) {
        Condition condition = new Condition(GoodsSku.class);
        Example.Criteria criteria = condition.createCriteria();
        criteria.andEqualTo("goodsBaseId", goodsId);
        return findByCondition(condition);
    }

    @Override
    public void save(GoodsSku model) {
        super.save(model);
        asyncExecutor.async(() -> {
            //上报GoodsSku到MQ中的GoodsBase中
            this.reportGoodsSkuToGoodsBase(model);
        });
    }

    @Override
    public void updateByPrimaryKeySelective(GoodsSku model) {
        super.updateByPrimaryKeySelective(model);
        asyncExecutor.async(() -> {
            if (ObjectUtils.isEmpty(model.getGoodsBaseId())) {
                //根据商品sku的Id查询商品sku
                GoodsSku goodsSku = findById(model.getId());
                if (ObjectUtils.isEmpty(goodsSku)) return;
                model.setGoodsBaseId(goodsSku.getGoodsBaseId());
            }
            //上报GoodsSku到MQ中的GoodsBase中
            this.reportGoodsSkuToGoodsBase(model);
        });
    }

    @Override
    public void deleteByIds(String ids) {
        String[] idList = ids.split(",");
        for (int i = 0; i < idList.length; i++) {
            Long goodsSkuId = Long.valueOf(idList[i]);
            //根据商品sku的Id查询商品sku
            GoodsSku goodsSku = findById(goodsSkuId);
            if (ObjectUtils.isEmpty(goodsSku)) continue;
            GoodsBase goodsBase = goodsBaseBusiness.findById(goodsSku.getGoodsBaseId());
            //删除商品
            deleteById(goodsSkuId);
            asyncExecutor.async(() -> {
                //上报GoodsSku到MQ中的GoodsBase中
                this.reportGoodsSkuToGoodsBase(goodsSku);
                RedisTools.template().delete(goodsBase.getShopId()+"_"+goodsSkuId);
            });
        }
    }

    /**
     * 更新上报商品sku到MQ中的GoodsBase中
     *
     * @param model 商品
     */
    private void reportGoodsSkuToGoodsBase(GoodsSku model) {
        //根据商品id查询商品的最高、最低价格
        GoodsMaxAndMinPriceResult goodsPrice = skuMapper.findPriceByGoodsBaseId(model.getGoodsBaseId());
        if (ObjectUtils.isEmpty(goodsPrice)) {
            goodsPrice = GoodsMaxAndMinPriceResult.builder()
                    .maxPrice(new BigDecimal(0))
                    .minPrice(new BigDecimal(0))
                    .build();
        }
        //根据goodsBaseId查询所有的GoodsSku
        GoodsSkuQueryParam skuQueryParam = GoodsSkuQueryParam.builder()
                .goodsBaseId(model.getGoodsBaseId())
                .build();
        List<GoodsSku> goodsSkuList = this.findGoodsSkuByParam(skuQueryParam);
        List<GoodsSkuDTO> goodsSkuDTOList = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(goodsSkuList)){
            goodsSkuDTOList = TransformUtils.transformList(goodsSkuList,GoodsSkuDTO.class);
        }
        //更新上报到MQ中
        GoodsBaseDTO goodsBaseDTO = GoodsBaseDTO.builder()
                .id(model.getGoodsBaseId())
                .maxPrice(goodsPrice.getMaxPrice())
                .minPrice(goodsPrice.getMinPrice())
                .goodsSkuList(goodsSkuDTOList)
                .build();
        RepositoryEventDto<GoodsBaseDTO> eventDto = RepositoryEventDto.buildWithUpdate(goodsBaseDTO);
        goodsReport.report(eventDto);
    }

}
